package com.juyu.miliao.api.service;

import com.juyu.miliao.api.dao.mysql.*;
import com.juyu.miliao.api.dao.redis.UserSignInInfoDaoRedis;
import com.juyu.miliao.api.dao.redis.usercache.UserInfoCache;
import com.juyu.miliao.api.domain.*;
import com.juyu.miliao.api.domain.vo.UserSignInInfoVo;
import com.juyu.miliao.common.constant.RecordTypeEnum;
import com.juyu.miliao.common.exception.ConsumeRuntimeException;
import com.juyu.miliao.common.util.MessageSystemUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author xuanqicheng
 * @create 2019-12-09:36
 */
@Service
@Slf4j
public class UserSignInService {

    @Autowired
    private UserSignInInfoDaoRedis userSignInInfoDaoRedis;

    @Autowired
    private UserSignInLogDao userSignInLogDao;

    @Autowired
    private UserWalletDao userWalletDao;

    @Autowired
    private UserVipDao userVipDao;

    @Autowired
    private UserInfoDao userInfoDao;

    @Autowired
    private UserInfoCache userInfoCache;

    @Autowired
    private BillDetailDao billDetailDao;


    public void addUserSignIn(long userId) throws IOException {
        boolean bl = userSignInInfoDaoRedis.getSignInStatus();
        if(!bl){
            throw new ConsumeRuntimeException("签到功能不可用");
        }
        UserSignInLog userSignInLog = userSignInLogDao.selectSignLogByUserId(userId);
        //如果null 代表用户是第一次签到
        if (userSignInLog == null) {
            userSignInLog = new UserSignInLog();
            userSignInLog.setCount(1);
            userSignInLog.setUserId(userId);
            try {
                userSignInLogDao.insert(userSignInLog);
                //进行奖励
                getSignInAward(userId,1);
            } catch (Exception ex) {
                log.error("用户签到错误：" + ex.getMessage());
                throw new ConsumeRuntimeException("今用户签到异常！");

            }
        } else {
            LocalDate signInDate = userSignInLog.getSignInDate();

            long betweenDays = ChronoUnit.DAYS.between(signInDate, LocalDate.now());
            int count = userSignInLog.getCount();
            //代表可以签到
            if (betweenDays == 1) {
                if (count == 7) {
                    //代表这是第一天签到
                    int num = userSignInLogDao.updateFirstDaySignIn(userId);
                    if (num == 1) {
                        getSignInAward(userId,1);
                    }
                }else{
                    int num = userSignInLogDao.updateSignIn(userId);
                    if(num ==1){
                        getSignInAward(userId,count+1);
                    }
                }
            }

            //代表不是连续签到，重置签到，从第一天开始计算
            if (betweenDays > 1) {
                int num = userSignInLogDao.updateFirstDaySignIn(userId);
                if (num == 1) {
                    getSignInAward(userId,1);
                }
            }

            if(betweenDays<=0){
                throw new ConsumeRuntimeException("今天已经签到，请勿重复签到！");
            }

        }
    }

    private void getSignInAward(long userId,int day) throws IOException {
        //进行奖励
        UserSignInInfo userSignInInfo = userSignInInfoDaoRedis.getUserSignInfoByDay(day);
        /**
         * 1:金币，2：vip
         */
        if (userSignInInfo.getType() == 1) {
            int gold = userSignInInfo.getNumber();
            // 获取帐号钱包
            UserWallet userWallet = userWalletDao.getUserWalletById(userId);

            userWallet.setDeposit(gold);

            userWalletDao.reviseDeposit(userWallet);

            // 保存消费记录
            BillDetail billDetail = new BillDetail();
            // 签到奖励金币
            billDetail.setRecordType(RecordTypeEnum.USER_SIGN_IN_GOLD.state);
            // 赚取钻石用户id
            billDetail.setInUserId(userId);
            // 消费金币数
            billDetail.setSpend(gold);

            billDetailDao.insertBillDetail(billDetail);

        } else {
            int vipDay = userSignInInfo.getNumber();
            //添加vip
            UserVip userVip = userVipDao.getUserVipById(userId);
            UserVip entity = new UserVip();
            if (userVip == null) {
                //无vip 或vip已到期
                entity.setVipDate(vipDay);
                entity.setStatus(1);
                entity.setVipPayType(0);
                entity.setUserId(userId);
                userVipDao.insertUserVip(entity);
                userInfoDao.updateUserIsVip(1, 0,1, userId);
            } else {//vip未到期

               userVipDao.updateUserVipDay(userVip.getVipDate()+vipDay,userVip.getUserVipId());
               userInfoDao.updateUserIsVip(1, 0,1, userId);
            }

            //发送系统消息：
            MessageSystemUtil.sendCustomSystemMessage(userId,"签到获取VIP"+userSignInInfo.getNumber()+"天");
            //更新userinfo
            userInfoCache.deleteUserCacheInfo(userId);
        }
    }

    public List<UserSignInInfoVo> getUserSignInList(long userId) {
        List<UserSignInInfo> list = userSignInInfoDaoRedis.getUserSignInfoList();

        UserSignInLog userSignInLog = userSignInLogDao.selectSignLogByUserId(userId);

        List<UserSignInInfoVo> userSignInInfoVoList = new ArrayList<>();
        if(userSignInLog==null){

            for(UserSignInInfo userSignInInfo : list){
                UserSignInInfoVo userSignInInfoVo = new UserSignInInfoVo();
                BeanUtils.copyProperties(userSignInInfo,userSignInInfoVo);
                userSignInInfoVo.setIsSignIn(false);
                userSignInInfoVoList.add(userSignInInfoVo);
            }
        }else{

            for(UserSignInInfo userSignInInfo : list){
                UserSignInInfoVo userSignInInfoVo = new UserSignInInfoVo();
                BeanUtils.copyProperties(userSignInInfo,userSignInInfoVo);

                LocalDate signInDate = userSignInLog.getSignInDate();
                long betweenDays = ChronoUnit.DAYS.between(signInDate, LocalDate.now());
                if(betweenDays>1 || userSignInLog.getCount()==7){
                    //不是连续签到，列表显示为都不签到
                    userSignInInfoVo.setIsSignIn(false);
                }else{
                    if(userSignInInfo.getDay()<=userSignInLog.getCount()){
                        userSignInInfoVo.setIsSignIn(true);
                    }else{
                        userSignInInfoVo.setIsSignIn(false);
                    }
                }


                userSignInInfoVoList.add(userSignInInfoVo);
            }
        }

        return userSignInInfoVoList;

    }

    /**
     * 检查用户签到状态
     * @param userId
     * @return
     */
    public Object checkUserSignIn(long userId) {
        UserSignInLog userSignInLog = userSignInLogDao.selectSignLogByUserId(userId);
        Map<String,Object> map = new HashMap<>(0);
        if(userSignInLog==null){
            map.put("isSignIn",false);
            return map;
        }else{
            long betweenDays = ChronoUnit.DAYS.between(userSignInLog.getSignInDate(), LocalDate.now());
            if(betweenDays<=0){
                map.put("isSignIn",true);
                return map;
            }else{
                map.put("isSignIn",false);
                return map;
            }
        }
    }

    public Object getSignInStatus() {
        boolean bl = userSignInInfoDaoRedis.getSignInStatus();
        Map<String,Object> map = new HashMap<>();
        map.put("switch",bl);
        return map;
    }
}
